package com.yanqu.road.server.manager.activity.sonhai;

import com.yanqu.road.dao.impl.activity.sonhai.SonHaiPlotDataDaoImpl;
import com.yanqu.road.dao.impl.activity.sonhai.SonHaiRegionDataDaoImpl;
import com.yanqu.road.dao.impl.activity.sonhai.SonHaiTeamDataDaoImpl;
import com.yanqu.road.entity.activity.douluodalu.data.DouLuoDaLuTeamData;
import com.yanqu.road.entity.activity.douluodalu.data.DouLuoDaLuUserData;
import com.yanqu.road.entity.activity.sonhai.config.SonHaiConfig;
import com.yanqu.road.entity.activity.sonhai.config.SonHaiEventConfig;
import com.yanqu.road.entity.activity.sonhai.config.SonHaiFloorConfig;
import com.yanqu.road.entity.activity.sonhai.data.*;
import com.yanqu.road.entity.activity.sonhai.enums.*;
import com.yanqu.road.entity.enums.eGamePlayerEventType;
import com.yanqu.road.entity.player.CrossUserBaseInfo;
import com.yanqu.road.entity.rank.cross.TeamBaseInfo;
import com.yanqu.road.pb.activity.SonHaiProto;
import com.yanqu.road.server.logic.MessageHelper;
import com.yanqu.road.server.manager.activity.ActivityTeamRankMgr;
import com.yanqu.road.server.manager.activity.commonteam.CommonTeam;
import com.yanqu.road.server.manager.activity.commonteam.CommonTeamMgr;
import com.yanqu.road.server.manager.user.CrossUserMgr;
import com.yanqu.road.server.protocol.Protocol;
import com.yanqu.road.utils.ListHelper;
import com.yanqu.road.utils.YanQuMessageUtils;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.property.PropertyHelper;
import com.yanqu.road.utils.string.StringUtils;
import org.apache.commons.collections.ListUtils;

import java.math.BigInteger;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantLock;

public class CrossSonHaiTeam extends SonHaiTeamData {

    /**
     * 队伍锁
     */
    private ReentrantLock lock = new ReentrantLock();

    /**
     * 活动配置
     */
    private SonHaiConfig sonHaiConfig;

    /**
     * 队伍成员
     */
    private Map<Long, CrossSonHaiUser> memberMap = new ConcurrentHashMap<>();

    /**
     * 区域MAP
     */
    private Map<Integer, SonHaiRegionData> regionMap = new ConcurrentHashMap<>();

    /**
     * 删除的区域LIST
     */
    private List<SonHaiRegionData> delRegionList = new ArrayList<>();

    /**
     * 存储
     */
    public void save() {
        SonHaiTeamDataDaoImpl teamDataDao = new SonHaiTeamDataDaoImpl();
        SonHaiRegionDataDaoImpl regionDataDao = new SonHaiRegionDataDaoImpl();
        SonHaiPlotDataDaoImpl plotDataDao = new SonHaiPlotDataDaoImpl();
        //队伍数据存储
        if (this.isInsertOption()) {
            teamDataDao.add(this);
        } else if (this.isUpdateOption()) {
            teamDataDao.update(this);
        }

        //区域数据存储
        for (SonHaiRegionData regionData : this.regionMap.values()) {
            if (regionData.isInsertOption()) {
                regionDataDao.add(regionData);
            } else if (regionData.isUpdateOption()) {
                regionDataDao.update(regionData);
            }
            //地块数据存储
            for (SonHaiPlotData plotData : regionData.getPlotDataMap().values()) {
                if (plotData.isInsertOption()) {
                    plotDataDao.add(plotData);
                } else if (plotData.isUpdateOption()) {
                    plotDataDao.update(plotData);
                }
            }
        }

        //删除的区域数据存储
        List<SonHaiRegionData> delRegionList;
        synchronized (this.delRegionList) {
            delRegionList = new ArrayList<>(this.delRegionList);
            this.delRegionList.clear();
        }
        for (SonHaiRegionData regionData:  delRegionList) {
            if (regionData.isInsertOption()) {
                regionDataDao.add(regionData);
            } else if (regionData.isUpdateOption()) {
                regionDataDao.update(regionData);
            }
            //地块数据存储
            for (SonHaiPlotData plotData : regionData.getPlotDataMap().values()) {
                if (plotData.isInsertOption()) {
                    plotDataDao.add(plotData);
                } else if (plotData.isUpdateOption()) {
                    plotDataDao.update(plotData);
                }
            }
        }
    }

    public CrossSonHaiTeam(SonHaiConfig sonHaiConfig, int groupId, int teamId, long leaderId) {
        super(sonHaiConfig.getActivityInfo().getActivityId(), groupId, teamId, leaderId);
        this.sonHaiConfig = sonHaiConfig;
    }

    public CrossSonHaiTeam(SonHaiConfig sonHaiConfig, SonHaiTeamData teamData, Map<Integer, SonHaiRegionData> teamRegionMap) {
        super(teamData);
        this.sonHaiConfig = sonHaiConfig;
        this.regionMap = teamRegionMap;
    }

    public void refreshConfig(SonHaiConfig sonHaiConfig) {
        this.sonHaiConfig = sonHaiConfig;
    }

    /**
     * 获取队伍锁
     * @return
     */
    public ReentrantLock getLock() {
        return lock;
    }

    /**
     * SET队伍成员
     * @param memberMap
     */
    public void setMemberMap(Map<Long, CrossSonHaiUser> memberMap) {
        this.memberMap = memberMap;
    }

    /**
     * 注入队伍成员
     * @param user
     */
    public void addMember(CrossSonHaiUser user) {
        this.memberMap.put(user.getUserId(), user);
    }

    /**
     * 获取成员MAP
     * @return
     */
    public Map<Long, CrossSonHaiUser> getMemberMap() {
        return this.memberMap;
    }

    /**
     * 添加区域
     * @param regionData
     */
    public void addRegion(SonHaiRegionData regionData) {
        this.regionMap.put(regionData.getRegionId(), regionData);
    }

    /**
     * 获取区域
     * @param regionId
     * @return
     */
    public SonHaiRegionData getRegion(int regionId) {
        return this.regionMap.get(regionId);
    }

    /**
     * 获取区域MAP
     * @return
     */
    public Map<Integer, SonHaiRegionData> getRegionMap() {
        return this.regionMap;
    }

    /**
     * 获取删除的区域列表
     * @return
     */
    public List<SonHaiRegionData> getDelRegionList() {
        return delRegionList;
    }

    /**
     * 获取玩家
     * @param userId
     * @return
     */
    public CrossSonHaiUser getUser(long userId) {
        CrossSonHaiActivity activity = CrossSonHaiActivityMgr.getActivity(this.getActivityId(), this.getGroupId());
        if (activity != null) {
            return activity.getUser(userId);
        }
        return null;
    }

    /**
     * 获取队伍的pvp目标玩家id集合
     * @return
     */
    public Set<Long> getPvpTargetUserIdSet() {
        Set<Long> pvpTargetUserIdSet = new HashSet<>();
        for (CrossSonHaiUser user : this.getMemberMap().values()) {
            //【营地】类型的地块
            SonHaiRegionData regionData = user.getRegionData();
            if (regionData != null) {
                List<SonHaiPlotData> plotDataList = regionData.getPlotDataListByType(SonHaiPlotTypeEnum.PLOT_TYPE_14.getType());
                if (plotDataList != null) {
                    for (SonHaiPlotData plotData : plotDataList) {
                        //未镇伏地块
                        if (plotData.getWinFlag() == SonHaiWinFlagEnum.WIN_NOT.getType() && plotData.getPvpUserId() > 0) {
                            pvpTargetUserIdSet.add(plotData.getPvpUserId());
                        }
                    }
                }
            }
        }
        return pvpTargetUserIdSet;
    }

    /**
     * 获取队伍eggId集合
     * @return
     */
    public Set<Integer> getEggIdSet() {
        Set<Integer> eggIdSet = new HashSet<>();
        //队友占领的蛋
        for (CrossSonHaiUser user : this.getMemberMap().values()) {
            eggIdSet.addAll(user.getUserEggDataMap().keySet());
        }
        //获取队伍兽蛋共享池
        Set<Integer> canBattleEggPool = this.getCanBattleEggPool();
        eggIdSet.addAll(canBattleEggPool);
        return eggIdSet;
    }

    /**
     * 获取队伍兽蛋共享池
     * @return
     */
    public Set<Integer> getCanBattleEggPool() {
        Set<Integer> eggIdSet = new HashSet<>();
        //队友面对的蛋
        for (SonHaiRegionData regionData : this.regionMap.values()) {
            List<SonHaiPlotData> eggPlotDataList = regionData.getPlotDataListByType(SonHaiPlotTypeEnum.PLOT_TYPE_13.getType());
            if (eggPlotDataList != null) {
                for (SonHaiPlotData eggPlot : eggPlotDataList) {
                    //没镇伏的蛋
                    if (eggPlot.getWinFlag() == SonHaiWinFlagEnum.WIN_NOT.getType() && eggPlot.getEggId() > 0) {
                        eggIdSet.add(eggPlot.getEggId());
                    }
                }
            }
        }
        return eggIdSet;
    }

    /**
     * 移除最早的蛋
     */
    public void removeOldEgg() {
        List<SonHaiPlotData> eggPlotList = new ArrayList<>();
        for (SonHaiRegionData regionData : this.regionMap.values()) {
            if (regionData != null) {
                List<SonHaiPlotData> plotDataList = regionData.getPlotDataListByType(SonHaiPlotTypeEnum.PLOT_TYPE_13.getType());
                if (plotDataList != null) {
                    for (SonHaiPlotData plotData : plotDataList) {
                        //未镇伏地块
                        if (plotData.getWinFlag() == SonHaiWinFlagEnum.WIN_NOT.getType() && plotData.getEggId() > 0) {
                            eggPlotList.add(plotData);
                        }
                    }
                }
            }
        }
        //根据时间排序一下
        eggPlotList.sort(Comparator.comparing(SonHaiPlotData::getCreateTime));
        if (!eggPlotList.isEmpty()) {
            SonHaiPlotData targetPlotData = eggPlotList.get(0);
            //地块移除蛋，丢失地块（镇伏，无奖励）
            targetPlotData.setWinFlag(SonHaiWinFlagEnum.WIN_YES.getType());
            targetPlotData.setWinTime(System.currentTimeMillis());
            targetPlotData.setGetRewardFlag(SonHaiRewardFlagEnum.GET_YES.getType());
            //蛋移除挂载地块
            CrossSonHaiActivity activity = CrossSonHaiActivityMgr.getActivity(this.getActivityId(), this.getGroupId());
            if (activity != null) {
                SonHaiEggData eggData = activity.getEgg(targetPlotData.getEggId());
                if (eggData != null) {
                    eggData.removeAttackMeUserPlot(targetPlotData.getUserId());
                }
            }
        }
    }

    /**
     * 移除区域
     * @param regionId
     */
    public void removeRegion(int regionId) {
        SonHaiRegionData delRegionData = this.regionMap.remove(regionId);
        if (delRegionData != null) {
            //删除区域
            delRegionData.delRegion();
            this.delRegionList.add(delRegionData);
            //那些已镇伏，未领取的奖励，通过邮件补发
            this.bfRemoveRegionNotGetReward(delRegionData);
            //未镇伏的营地类型（PVP）地块，移除pvp目标
            List<SonHaiPlotData> plotDataList = delRegionData.getPlotDataListByType(SonHaiPlotTypeEnum.PLOT_TYPE_14.getType());
            if (plotDataList != null) {
                for (SonHaiPlotData plotData : plotDataList) {
                    if (plotData.getWinFlag() == SonHaiWinFlagEnum.WIN_NOT.getType() && plotData.getPvpUserId() > 0) {
                        //pvp玩家移除针对他的地块
                        CrossSonHaiUser pvpUser = this.getUser(plotData.getPvpUserId());
                        if (pvpUser != null) {
                            pvpUser.removeAttackMeUserPlot(plotData.getUserId());
                        }
                    }
                }
            }
        }
    }

    /**
     * 那些已镇伏，未领取的奖励，通过邮件补发
     * @param delRegionData
     */
    private void bfRemoveRegionNotGetReward(SonHaiRegionData delRegionData) {
        //那些已镇伏，未领取的奖励，通过邮件补发
        Map<Long, Property> userRewardMap = new HashMap<>();//道具奖励
        Map<Long, Long> userAuraScoreMap = new HashMap<>();//山海灵气

        //地块奖励
        for (SonHaiPlotData plotData : delRegionData.getPlotDataMap().values()) {
            //已镇伏,未领取的奖励的地块
            if (plotData.getWinFlag() == SonHaiWinFlagEnum.WIN_YES.getType()) {
                //排除无归属地块，目前就兽王地块
                if (plotData.getUserId() <= 0) {
                    continue;
                }
                //地块事件配置
                SonHaiEventConfig eventConfig = this.sonHaiConfig.getEventConfig(plotData.getPlotId());
                //镇伏地块奖励
                Property plotReward;
                if (!eventConfig.getChooseRewardList().isEmpty()) {
                    //2选1奖励
                    //判断奖励是否领取
                    if (plotData.getChooseRewardFlag() != SonHaiRewardFlagEnum.GET_NOT.getType()) {
                        continue;
                    }
                    //设置领取状态
                    plotData.setChooseRewardFlag(SonHaiRewardFlagEnum.GET_YES.getType());
                    //解析奖励
                    plotReward = PropertyHelper.parseStringToProperty(eventConfig.getChooseRewardList().get(0));
                } else {
                    //镇伏奖励
                    //判断奖励是否领取
                    if (plotData.getGetRewardFlag() != SonHaiRewardFlagEnum.GET_NOT.getType()) {
                        continue;
                    }
                    //设置领取状态
                    plotData.setGetRewardFlag(SonHaiRewardFlagEnum.GET_YES.getType());
                    //解析奖励
                    plotReward = PropertyHelper.parseStringToProperty(plotData.getReward());
                }

                if (plotReward == null || plotReward.isNothing()) {
                    continue;
                }
                //奖励数据
                Property reward = userRewardMap.computeIfAbsent(plotData.getUserId(), (userId) -> new Property());
                reward.addProperty(plotReward);

                //山海灵气奖励
                long plotAuraScore = plotData.getExtraAuraScore();
                if (plotAuraScore > 0) {
                    if (!userAuraScoreMap.containsKey(plotData.getUserId())) {
                        userAuraScoreMap.put(plotData.getUserId(), 0L);
                    }
                    userAuraScoreMap.put(plotData.getUserId(), userAuraScoreMap.get(plotData.getUserId()) + plotAuraScore);
                }
            }
        }

        //兽王奖励
        SonHaiBeastBossData bossData = delRegionData.getBeastBoss();
        if (bossData.getWinFlag() == SonHaiWinFlagEnum.WIN_YES.getType()) {
            //事件配置
            SonHaiEventConfig eventConfig = this.sonHaiConfig.getEventConfig(bossData.getEventId());
            //boss奖励
            Property bossReward = PropertyHelper.parseNewStringToProperty(eventConfig.getReward());
            for (CrossSonHaiUser member : this.memberMap.values()) {
                //未领取兽王奖励的队员，补发
                if (!bossData.checkReceiveReward(member.getUserId())) {
                    //设置已领取
                    bossData.addRewardUserIdSet(member.getUserId());
                    delRegionData.setUpdateOption();
                    //镇伏奖励
                    Property reward = userRewardMap.computeIfAbsent(member.getUserId(), (userId) -> new Property());
                    reward.addProperty(bossReward);

                    //山海灵气
                    List<SonHaiPlotData> bossPlotList = delRegionData.getBossPlotDataList();
                    long baseAddAuraScore = eventConfig.getPvpScore();
                    int auraScoreOpRate = member.getAuraScoreOpRate(bossPlotList.get(0), true);//buff:山海灵气加成率
                    long auraScoreOpValue = member.getAuraScoreOpValue(bossPlotList.get(0), true);//buff:山海灵气加成值
                    long plotAuraScore = member.countAureScore(baseAddAuraScore, auraScoreOpRate, auraScoreOpValue);

                    if (plotAuraScore > 0) {
                        if (!userAuraScoreMap.containsKey(member.getUserId())) {
                            userAuraScoreMap.put(member.getUserId(), 0L);
                        }
                        userAuraScoreMap.put(member.getUserId(), userAuraScoreMap.get(member.getUserId()) + plotAuraScore);
                    }
                }
            }
        }

        //遍历玩家。发放山海灵气
        for (Map.Entry<Long, Long> entry : userAuraScoreMap.entrySet()) {
            long userId = entry.getKey();
            long auraScore = entry.getValue();
            CrossSonHaiUser user = this.memberMap.get(userId);
            this.changeAuraScore(user, auraScore);
        }

        //遍历玩家。发放奖励
        for (Map.Entry<Long, Property> entry : userRewardMap.entrySet()) {
            long userId = entry.getKey();
            Property reward = entry.getValue();
            //通知区服，发送邮件
            CrossUserBaseInfo userBaseInfo = CrossUserMgr.getCrossUserBaseInfo(userId);
            if (userBaseInfo != null) {
                SonHaiProto.SonHaiSendRegionResetRewardMsg.Builder msg = SonHaiProto.SonHaiSendRegionResetRewardMsg.newBuilder();
                msg.setReward(PropertyHelper.parsePropertyToString(reward));
                MessageHelper.sendPacket(userBaseInfo.getUserBaseInfo().getServerId(), userBaseInfo.getUserId(), YanQuMessageUtils.buildMessage(Protocol.S_SON_HAI_SEND_REGION_RESET_REWARD_FROM_CROSS, msg));
            }
        }
    }

    /**
     * 获取【探险互助】日志
     * @param userId
     * @return
     */
    public List<SonHaiPlotData> getNormalBattleLogList(long userId) {
        //获取普通战斗地块List
        List<SonHaiPlotData> normalBattlePlotList = new ArrayList<>();
        for (SonHaiRegionData regionData : this.regionMap.values()) {
            List<SonHaiPlotData> plotDataList = regionData.getBattleLogListByBattleType(userId, SonHaiPlotBattleTypeEnum.PLOT_BATTLE_TYPE_NORMAL, this.sonHaiConfig);
            normalBattlePlotList.addAll(plotDataList);
        }
        return normalBattlePlotList;
    }

    /**
     * 获取【兽王踪迹】日志
     * @return
     */
    public List<SonHaiBeastBossData> getBossBattleLogList(long userId) {
        //获取兽王战斗List
        List<SonHaiBeastBossData> bossBattlePlotList = new ArrayList<>();
        for (SonHaiRegionData regionData : this.regionMap.values()) {
            //判断寻踪进度是否满足
            SonHaiFloorConfig floorConfig = this.sonHaiConfig.getFloorConfig(regionData.getRegionId());
            if (regionData.getProgress() >= floorConfig.getNeedSchedule()) {
                SonHaiBeastBossData boss = regionData.getBeastBoss();
                //boss未镇伏 || 奖励未领取
                if (boss.getWinFlag() == SonHaiWinFlagEnum.WIN_NOT.getType()) {
                    bossBattlePlotList.add(boss);
                } else {
                    if (!boss.checkReceiveReward(userId)) {
                        bossBattlePlotList.add(boss);
                    }
                }
            }
        }
        return bossBattlePlotList;
    }

    /**
     * 获取【兽蛋共享】日志
     * @param userId
     * @return
     */
    public List<SonHaiPlotData> getEggBattleLogList(long userId) {
        //获取普通战斗地块List
        List<SonHaiPlotData> eggBattlePlotList = new ArrayList<>();
        for (SonHaiRegionData regionData : this.regionMap.values()) {
            List<SonHaiPlotData> plotDataList = regionData.getBattleLogListByBattleType(userId, SonHaiPlotBattleTypeEnum.PLOT_BATTLE_TYPE_EGG, this.sonHaiConfig);
            eggBattlePlotList.addAll(plotDataList);
        }
        return eggBattlePlotList;
    }

    /**
     * 队伍榜单变更
     */
    public void changeTeamRank() {
        int activityId = this.sonHaiConfig.getActivityInfo().getActivityId();
        //获取队伍的山海灵气
        long auraScore = this.getTeamAuraScore();
        //队伍榜单变更
        CommonTeamMgr.changeTeamRankScore(activityId, this.getGroupId(), eGamePlayerEventType.SonHaiTeamRank.getValue(), this.getTeamId(), auraScore, 0);
    }

    /**
     * 获取队伍的山海灵气
     * @return
     */
    private long getTeamAuraScore() {
        long auraScore = 0;
        for (CrossSonHaiUser member : this.memberMap.values()) {
            auraScore += member.getAuraScore();
        }
        return auraScore;
    }

    /**
     * 变更山海灵气
     * @param user
     * @param addAuraScore
     */
    public void changeAuraScore(CrossSonHaiUser user, long addAuraScore) {
        user.addAuraScore(addAuraScore);
        //队伍榜单变更
        this.changeTeamRank();
    }

    /**
     * 获取队伍积分
     * @return
     */
    public long getTeamScore() {
        long score = 0;
        for (CrossSonHaiUser member : this.memberMap.values()) {
            score += member.getScore();
        }
        return score;
    }

    /**
     * 同步队伍积分变更
     */
    public void syncTeamUserScore() {
        long teamScore = this.getTeamScore();
        for (CrossSonHaiUser member : this.memberMap.values()) {
            this.syncMemberTeamUserScore(member.getServerId(), member.getUserId(), teamScore);
        }
    }

    /**
     * 成员队伍积分变更
     * @param serverId
     * @param userId
     * @param teamScore
     */
    public void syncMemberTeamUserScore(long serverId, long userId, long teamScore) {
        SonHaiProto.SonHaiTeamScoreChangeFromCrossMsg.Builder msg = SonHaiProto.SonHaiTeamScoreChangeFromCrossMsg.newBuilder();
        msg.setActivityId(this.sonHaiConfig.getActivityInfo().getActivityId());
        msg.setTeamScore(teamScore);
        MessageHelper.sendPacket(serverId, userId, YanQuMessageUtils.buildMessage(Protocol.S_SON_HAI_TEAM_SCORE_CHANGE_FROM_CROSS, msg));
    }

    /**
     * 获取区域玩家SET
     * @param regionId
     * @return
     */
    public Set<Long> getRegionUserIds(int regionId) {
        Set<Long> userIds = new HashSet<>();
        for (CrossSonHaiUser user : this.memberMap.values()) {
            if (regionId == user.getRegionId()) {
                userIds.add(user.getUserId());
            }
        }
        return userIds;
    }
}
